package controller

import (
	"delivery-server/service"
	"delivery-server/utils"
	"delivery-server/utils/response"
	"encoding/json"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/mvc"
	"github.com/kataras/iris/v12/sessions"
	"strconv"
)

// RestaurantController 餐馆控制器
type RestaurantController struct {

	// 上下文对象
	Ctx iris.Context

	// restaurant功能实体
	Service service.RestaurantService

	// session对象
	Session *sessions.Session
}

// PostLogin 用户登录
// 接口：/restaurant/login
// username：用户名
// password：密码
func (rc *RestaurantController) PostLogin() mvc.Result {

	// 获取请求体参数
	username := rc.Ctx.FormValue("username")
	password := rc.Ctx.FormValue("password")

	// 数据参数检验
	if username == "" || password == "" {
		return response.ParamLack()
	}

	// 根据用户名和密码查询用户id
	userIdStr, exist := rc.Service.UserLogin(username, password)

	// 该用户不存在，即用户名或密码错误
	if !exist {
		return response.AccountErr()
	}

	// 获取int类型的用户id
	userId, err := strconv.Atoi(userIdStr)
	if err != nil {
		panic(err.Error())
	}

	// 设置session
	userByte, _ := json.Marshal(userIdStr)
	rc.Session.Set("restaurant", userByte)

	// 根据用户id查询该用户所掌管的餐馆id
	restaurantIdStr, isMaster := rc.Service.QueryRestaurantByUser(userId)

	// 该用户拥有一家餐馆
	if isMaster {

		// 获取int类型的餐馆id
		restaurantId, err := strconv.Atoi(restaurantIdStr)
		if err != nil {
			panic(err.Error())
		}

		return response.Success(iris.Map{
			"identity":     1,
			"userId":       userId,
			"restaurantId": restaurantId,
		})
	}

	// 根据用户id查询该用户的员工id
	stafferIdStr, restaurantIdStr, isStaffer := rc.Service.QueryStafferByUser(userId)

	// 该用户是员工
	if isStaffer {

		// 获取int类型的员工id
		stafferId, err := strconv.Atoi(stafferIdStr)
		if err != nil {
			panic(err.Error())
		}

		// 获取int类型的餐馆id
		restaurantId, err := strconv.Atoi(restaurantIdStr)
		if err != nil {
			panic(err.Error())
		}

		return response.Success(iris.Map{
			"identity":     2,
			"userId":       userId,
			"restaurantId": restaurantId,
			"stafferId":    stafferId,
		})
	}

	// 返回用户id
	return response.Success(iris.Map{
		"identity": 0,
		"userId":   userId,
	})
}

// PostCreate 创建餐馆
// 接口：restaurant/create
// userId：用户id
// name：餐馆名称
// description：餐馆描述
func (rc *RestaurantController) PostCreate() mvc.Result {

	// 获取请求体参数
	userIdStr := rc.Ctx.FormValue("userId")
	name := rc.Ctx.FormValue("name")
	description := rc.Ctx.FormValue("description")

	// 参数非空校验
	if userIdStr == "" || name == "" || description == "" {
		return response.ParamLack()
	}

	// 获取整型用户id
	userId, err := strconv.Atoi(userIdStr)
	if err != nil {
		return response.ParamErr()
	}

	// 尝试创建餐馆
	code := rc.Service.TryToCreateRestaurant(name, description, userId)
	return response.Template(code, code == response.SuccessCode)
}

// PostJoin 加入餐馆
// 接口：/restaurant/join
// userId：用户id
// restaurantId：餐馆id
func (rc *RestaurantController) PostJoin() mvc.Result {
	// 获取请求体参数
	userIdStr := rc.Ctx.FormValue("userId")
	restaurantIdStr := rc.Ctx.FormValue("restaurantId")

	// 参数非空校验
	if userIdStr == "" || restaurantIdStr == "" {
		return response.ParamLack()
	}

	// 获取整型用户id
	userId, err := strconv.Atoi(userIdStr)
	if err != nil {
		return response.ParamErr()
	}

	restaurantId, err := strconv.Atoi(restaurantIdStr)
	if err != nil {
		return response.ParamErr()
	}

	// 尝试加入餐馆
	code := rc.Service.TryToJoinRestaurant(userId, restaurantId)
	return response.Template(code, code == response.SuccessCode)
}

// PostQuery 搜索餐馆
// 接口：/restaurant/query
// query：搜索片段
func (rc *RestaurantController) PostQuery() mvc.Result {

	// 获取请求体
	query := rc.Ctx.FormValue("query")

	// 参数非空校验
	if query == "" {
		return response.ParamLack()
	}

	// 根据片段进行模糊搜索
	results, exist := rc.Service.FuzzyQueryRestaurantByName(query)

	// 未找到匹配结果
	if !exist {
		return response.NoMatch()
	}

	return response.Success(results)
}

// PostApplicationAll 查看入职申请
// 接口：/restaurant/application/all
// restaurantId：餐馆id
func (rc *RestaurantController) PostApplicationAll() mvc.Result {

	// 获取请求体参数
	restaurantIdStr := rc.Ctx.FormValue("restaurantId")

	// 参数非空校验
	if restaurantIdStr == "" {
		return response.ParamLack()
	}

	// 获取整型餐馆id
	restaurantId, err := strconv.Atoi(restaurantIdStr)
	if err != nil {
		return response.ParamErr()
	}

	// 获取请求数据
	results, err := rc.Service.QueryApplications(restaurantId)
	if err != nil {
		return response.ServerErr()
	}

	return response.Success(results)
}

// PostExamine 审批入职申请
// 接口：/restaurant/examine
// restaurantId：餐馆id
// userId：用户id
// salary：工资（为0表示拒绝）
func (rc *RestaurantController) PostExamine() mvc.Result {

	// 获取请求体参数
	restaurantIdStr := rc.Ctx.FormValue("restaurantId")
	userIdStr := rc.Ctx.FormValue("userId")
	salaryStr := rc.Ctx.FormValue("salary")

	// 参数非空校验
	if restaurantIdStr == "" || userIdStr == "" || salaryStr == "" {
		return response.ParamLack()
	}

	// 获取整型餐馆id
	restaurantId, err := strconv.Atoi(restaurantIdStr)
	if err != nil {
		return response.ParamErr()
	}

	// 获取整型用户id
	userId, err := strconv.Atoi(userIdStr)
	if err != nil {
		return response.ParamErr()
	}

	// 获取整型薪资
	salary, err := strconv.Atoi(salaryStr)
	if err != nil {
		return response.ParamErr()
	}

	if salary > 0 {
		// 同意入职
		err = rc.Service.EmployStaffer(restaurantId, userId, salary)
		if err != nil {
			response.ServerErr()
		}
	} else {
		// 拒绝入职
		err = rc.Service.RefuseStaffer(restaurantId, userId)
		if err != nil {
			response.ServerErr()
		}
	}

	// 申请成功
	return response.Success(true)
}

// PostInformationGet 查看餐馆信息
// 接口：/restaurant/information/get
// restaurantId：餐馆id
func (rc *RestaurantController) PostInformationGet() mvc.Result {

	restaurantIdStr := rc.Ctx.FormValue("restaurantId")

	if restaurantIdStr == "" {
		return response.ParamLack()
	}

	restaurantId, err := strconv.Atoi(restaurantIdStr)
	if err != nil {
		return response.ParamErr()
	}

	results, err := rc.Service.QueryInformation(restaurantId)
	if err != nil {
		return response.ServerErr()
	}

	return response.Success(results[0])
}

// PostInformationSet 设置餐馆信息
// 接口：/restaurant/information/set
// restaurantId：餐馆id
// placeId：地点id
// description：餐馆描述
func (rc *RestaurantController) PostInformationSet() mvc.Result {

	restaurantStr := rc.Ctx.FormValue("restaurantId")
	placeIdStr := rc.Ctx.FormValue("placeId")
	description := rc.Ctx.FormValue("description")

	// 除了餐馆描述之外，其他参数不能为空
	if restaurantStr == "" || placeIdStr == "" {
		return response.ParamLack()
	}

	restaurantId, err := strconv.Atoi(restaurantStr)
	if err != nil {
		return response.ParamErr()
	}

	placeId, err := strconv.Atoi(placeIdStr)
	if err != nil {
		return response.ParamErr()
	}

	err = rc.Service.UpdateInformation(restaurantId, placeId, description)

	if err != nil {
		return response.ServerErr()
	}

	return response.Success(true)
}

// PostStafferAll 查看员工
// 接口：/restaurant/staffer/all
// restaurantId：餐馆id
func (rc *RestaurantController) PostStafferAll() mvc.Result {

	restaurantIdStr := rc.Ctx.FormValue("restaurantId")

	if restaurantIdStr == "" {
		return response.ParamLack()
	}

	restaurantId, err := strconv.Atoi(restaurantIdStr)
	if err != nil {
		return response.ParamErr()
	}

	results, err := rc.Service.QueryStaff(restaurantId)
	if err != nil {
		return response.ServerErr()
	}

	return response.Success(results)
}

// PostStafferDelete 删除员工
// 接口：/restaurant/staffer/delete
// restaurantId：餐馆id
// userId：用户id
func (rc *RestaurantController) PostStafferDelete() mvc.Result {

	restaurantIdStr := rc.Ctx.FormValue("restaurantId")
	userIdStr := rc.Ctx.FormValue("userId")

	if restaurantIdStr == "" || userIdStr == "" {
		return response.ParamLack()
	}

	restaurantId, err := strconv.Atoi(restaurantIdStr)
	if err != nil {
		return response.ParamErr()
	}

	userId, err := strconv.Atoi(userIdStr)
	if err != nil {
		return response.ParamErr()
	}

	err = rc.Service.DeleteStaffer(restaurantId, userId)
	if err != nil {
		return response.ServerErr()
	}

	return response.Success(true)
}

// PostStafferSalarySet 修改员工工资
// 接口：/restaurant/staffer/salary/set
// restaurantId：餐馆id
// userId：用户id
// salary：工资
func (rc *RestaurantController) PostStafferSalarySet() mvc.Result {

	// 获取请求体参数
	restaurantIdStr := rc.Ctx.FormValue("restaurantId")
	userIdStr := rc.Ctx.FormValue("userId")
	salaryStr := rc.Ctx.FormValue("salary")

	// 参数非空校验
	if restaurantIdStr == "" || userIdStr == "" || salaryStr == "" {
		return response.ParamLack()
	}

	// 获取整型餐馆id
	restaurantId, err := strconv.Atoi(restaurantIdStr)
	if err != nil {
		return response.ParamErr()
	}

	// 获取整型用户id
	userId, err := strconv.Atoi(userIdStr)
	if err != nil {
		return response.ParamErr()
	}

	// 获取整型薪资
	salary, err := strconv.Atoi(salaryStr)
	if err != nil {
		return response.ParamErr()
	}

	// 更新数据
	err = rc.Service.UpdateStafferSalary(restaurantId, userId, salary)
	if err != nil {
		return response.ServerErr()
	}

	return response.Success(true)
}

// PostDishAdd 增加菜品
// 接口：/restaurant/dish/add
// restaurantId：餐馆id
// categoryId：菜式id
// name：菜品名称
// description：菜品描述
func (rc *RestaurantController) PostDishAdd() mvc.Result {

	restaurantIdStr := rc.Ctx.FormValue("restaurantId")
	categoryIdStr := rc.Ctx.FormValue("categoryId")
	name := rc.Ctx.FormValue("name")
	priceStr := rc.Ctx.FormValue("price")
	description := rc.Ctx.FormValue("description")

	if restaurantIdStr == "" || categoryIdStr == "" || name == "" || priceStr == "" {
		return response.ParamLack()
	}

	restaurantId, err := strconv.Atoi(restaurantIdStr)
	if err != nil {
		return response.ParamErr()
	}

	categoryId, err := strconv.Atoi(categoryIdStr)
	if err != nil {
		return response.ParamErr()
	}

	price, err := strconv.Atoi(priceStr)
	if err != nil {
		response.ParamErr()
	}

	err = rc.Service.InsertDish(restaurantId, categoryId, price, name, description)
	if err != nil {
		return response.ServerErr()
	}

	return response.Success(true)
}

// PostDishAll 查看所有菜品
// 接口：/restaurant/dish/all
// restaurantId：餐馆id
func (rc *RestaurantController) PostDishAll() mvc.Result {

	restaurantIdStr := rc.Ctx.FormValue("restaurantId")

	if restaurantIdStr == "" {
		return response.ParamLack()
	}

	restaurantId, err := strconv.Atoi(restaurantIdStr)
	if err != nil {
		return response.ParamErr()
	}

	results, err := rc.Service.QueryDish(restaurantId)
	if err != nil {
		return response.ServerErr()
	}

	return response.Success(results)
}

// PostDishDelete 删除餐品
// 接口：/restaurant/dish/delete
// dishId：菜品id
func (rc *RestaurantController) PostDishDelete() mvc.Result {

	dishIdStr := rc.Ctx.FormValue("dishId")

	if dishIdStr == "" {
		return response.ParamLack()
	}

	dishId, err := strconv.Atoi(dishIdStr)
	if err != nil {
		return response.ParamErr()
	}

	err = rc.Service.DeleteDish(dishId)
	if err != nil {
		return response.ServerErr()
	}

	return response.Success(true)
}

// PostOrderWait 待接取订单
// 接口：/restaurant/order/wait
// restaurantId：餐馆id
func (rc *RestaurantController) PostOrderWait() mvc.Result {

	restaurantId := rc.Ctx.FormValue("restaurantId")

	notNull := utils.CheckNotNull(restaurantId)
	if !notNull {
		return response.ParamLack()
	}

	paramsInt, convertSuccess := utils.CheckInteger(restaurantId)
	if !convertSuccess {
		return response.ParamErr()
	}

	results, err := rc.Service.AllWaitOrder(paramsInt[restaurantId])
	if err != nil {
		return response.ServerErr()
	}

	return response.Success(results)
}

// PostOrderProgress 正在派送的订单
// 接口：/restaurant/order/progress
// restaurantId：餐馆id
// stafferId：员工id
func (rc *RestaurantController) PostOrderProgress() mvc.Result {

	restaurantId := rc.Ctx.FormValue("restaurantId")
	stafferId := rc.Ctx.FormValue("stafferId")

	// 馆主查找
	if stafferId == "" {
		notNull := utils.CheckNotNull(restaurantId)
		if !notNull {
			return response.ParamLack()
		}

		paramsInt, convertSuccess := utils.CheckInteger(restaurantId)
		if !convertSuccess {
			return response.ParamErr()
		}

		results, err := rc.Service.AllProgressOrder(paramsInt[restaurantId])
		if err != nil {
			return response.ServerErr()
		}

		return response.Success(results)
	} else {
		paramsInt, convertSuccess := utils.CheckInteger(stafferId)
		if !convertSuccess {
			return response.ParamErr()
		}

		results, err := rc.Service.StafferProgressOrder(paramsInt[stafferId])
		if err != nil {
			return response.ServerErr()
		}

		return response.Success(results)
	}
}

// PostOrderFinish 查找已完成的订单
// 接口：/restaurant/order/finish
// restaurantId：餐馆id
// stafferId：员工id
func (rc *RestaurantController) PostOrderFinish() mvc.Result {

	restaurantId := rc.Ctx.FormValue("restaurantId")
	stafferId := rc.Ctx.FormValue("stafferId")

	// 馆主查找
	if stafferId == "" {
		notNull := utils.CheckNotNull(restaurantId)
		if !notNull {
			return response.ParamLack()
		}

		paramsInt, convertSuccess := utils.CheckInteger(restaurantId)
		if !convertSuccess {
			return response.ParamErr()
		}

		results, err := rc.Service.AllFinishOrder(paramsInt[restaurantId])
		if err != nil {
			return response.ServerErr()
		}

		return response.Success(results)
	} else {
		paramsInt, convertSuccess := utils.CheckInteger(stafferId)
		if !convertSuccess {
			return response.ParamErr()
		}

		results, err := rc.Service.StafferFinishOrder(paramsInt[stafferId])
		if err != nil {
			return response.ServerErr()
		}

		return response.Success(results)
	}
}

// PostOrderStart 接收订单
// 接口：/restaurant/order/start
// stafferId：员工id
// orderId：订单id
func (rc *RestaurantController) PostOrderStart() mvc.Result {

	stafferId := rc.Ctx.FormValue("stafferId")
	orderId := rc.Ctx.FormValue("orderId")

	notNull := utils.CheckNotNull(stafferId, orderId)
	if !notNull {
		return response.ParamLack()
	}

	paramsInt, convertSuccess := utils.CheckInteger(stafferId, orderId)
	if !convertSuccess {
		return response.ParamErr()
	}

	code := rc.Service.StartOrder(paramsInt[stafferId], paramsInt[orderId])
	return response.Template(code, code == response.SuccessCode)
}

// PostOrderEnd 完成订单
// 接口：/restaurant/order/end
// orderId：订单id
func (rc *RestaurantController) PostOrderEnd() mvc.Result {

	stafferId := rc.Ctx.FormValue("stafferId")
	orderId := rc.Ctx.FormValue("orderId")

	notNull := utils.CheckNotNull(stafferId, orderId)
	if !notNull {
		return response.ParamLack()
	}

	paramsInt, convertSuccess := utils.CheckInteger(stafferId, orderId)
	if !convertSuccess {
		return response.ParamErr()
	}

	err := rc.Service.EndOrder(paramsInt[stafferId], paramsInt[orderId])
	if err != nil {
		return response.ServerErr()
	}

	return response.Success(true)
}
